﻿using System;
using System.Collections.Generic;
using DatabaseGroup.SSIS.SourceAdapters.View;
using DatabaseGroup.SSIS.SourceAdapters.Model;

namespace DatabaseGroup.SSIS.SourceAdapters.Presenter
{
    /// <summary>
    /// Presenter for handling the Preview tab view
    /// </summary>
    public class PreviewTabPresenter
    {
        private readonly IEditorPreviewView _view;
        private readonly IComponentModel _componentModel;
        private readonly ISourceFileModel _fileModel;
        private PreviewTabSettings _settings;

        /// <summary>
        /// Initializes a new instance of the PreviewTabPresenter class
        /// using the view, propertiesModel and fileModel
        /// </summary>
        /// <param name="view">An instance of an IEditorPreviewView</param>
        /// <param name="componentModel">An instance of an IComponentPropertiesModel</param>
        /// <param name="fileModel">An instance of an ISourceFileModel</param>
        public PreviewTabPresenter(IEditorPreviewView view, IComponentModel componentModel, ISourceFileModel fileModel)
        {
            _view = view;
            _componentModel = componentModel;
            _fileModel = fileModel;

            InitializeView();

            view.ViewSettings += view_ViewSettings;
            view.RefreshPreview += view_RefreshPreview;
        }

        /// <summary>
        /// Binds the view with the current settings object
        /// and refreshed the preview rows displayed
        /// </summary>
        /// <param name="sender">The View</param>
        /// <param name="e"></param>
        private void view_ViewSettings(object sender, TabEventArgs e)
        {
            if (e.Tab != EditorViewTab.Preview && e.Tab != EditorViewTab.ANY)
                return;

            _view.BindPreviewTab(_settings);
            RefreshPreviewRows(_settings.DataRowsToSkip);
        }

        /// <summary>
        /// View has requested preview rows should be updated based on current settings,
        /// so this refreshed the view
        /// </summary>
        /// <param name="sender">The View</param>
        /// <param name="e"></param>
        private void view_RefreshPreview(object sender, EventArgs e)
        {
            RefreshPreviewRows(_settings.DataRowsToSkip);
        }

        /// <summary>
        /// Creates a new Preview settings object and binds the preview tab to it
        /// </summary>
        private void InitializeView()
        {
            _settings = new PreviewTabSettings();
            _view.BindPreviewTab(_settings);
        }

        /// <summary>
        /// Loads a sample of data from the source file
        /// and displays it on the view
        /// </summary>
        /// <param name="rowsToSkip">The number of initial rows to skip</param>
        private void RefreshPreviewRows(int rowsToSkip)
        {
            PresenterUtils.ConfigureFileModel(_fileModel, _componentModel, _view);
            GeneralTabSettings generalTabSettings = _view.GetTabSettings<GeneralTabSettings>(EditorViewTab.General);
            
            List<string[]> fileRows = new List<string[]>();
            List<string[]> rows = new List<string[]>();

            if (_componentModel.IsFileConnectionValid(generalTabSettings.FileConnection))
                fileRows = _fileModel.GetRows(rowsToSkip, 100, true);

            List<string> headers = new List<string>();
            List<ColumnProperty> columns = _view.GetTabSettings<AdvanceTabSettings>(EditorViewTab.Advance).Columns;

            // build the list of headers based on all the columns configured
            // as standard output columns
            foreach (ColumnProperty column in columns)
            {
                if (column.IsForOutput)
                    headers.Add(column.Name);
            }

            // build the list of rows, only including column data for the 
            // columns configured as standard output columns
            foreach (string[] row in fileRows)
            {
                List<string> rowBuilder = new List<string>();

                for (int colIndex = 0; colIndex < row.Length; colIndex++)
                {
                    if (colIndex >= columns.Count)
                        break;

                    if (columns[colIndex].IsForOutput)
                        rowBuilder.Add(row[colIndex]);
                }

                if (rowBuilder.Count > 0)
                    rows.Add(rowBuilder.ToArray());
            }
            
            _view.PopulatePreviewRows(headers, rows);
        }
    }
}
